package com.joysuch.wwyt.patrol.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joysuch.wwyt.core.constant.Constants;
import com.joysuch.wwyt.patrol.constant.ExceptProcessStatus;
import com.joysuch.wwyt.patrol.entity.PatrolRecordItem;
import com.joysuch.wwyt.patrol.entity.PatrolTask;
import com.joysuch.wwyt.patrol.entity.dto.ItemCheckResultDto;
import com.joysuch.wwyt.patrol.entity.dto.TaskRecordItemDto;
import com.joysuch.wwyt.patrol.entity.vo.WebTaskRecordDeviceVo;
import com.joysuch.wwyt.patrol.entity.vo.WebTaskRecordItemVo;
import com.joysuch.wwyt.patrol.mapper.PatrolRecordItemMapper;
import com.joysuch.wwyt.patrol.mapper.PatrolTaskMapper;
import com.joysuch.wwyt.patrol.service.PatrolRecordItemService;
import com.joysuch.wwyt.patrol.service.PatrolTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author heqifeng
 * @since 2022-03-03
 */
@Slf4j
@Service
public class PatrolRecordItemServiceImpl extends ServiceImpl<PatrolRecordItemMapper, PatrolRecordItem> implements PatrolRecordItemService {

    @Autowired
    private PatrolRecordItemMapper mapper;
    @Autowired
    private PatrolTaskMapper taskMapper;
    @Autowired
    private PatrolTaskService taskService;

    @Override
    public void repair(Long id) {
        PatrolRecordItem recordItem = getById(id);
        recordItem.setExceptHandel(ExceptProcessStatus.PROCESSING);
        saveOrUpdate(recordItem);
        PatrolTask task = mapper.selectTaskByItemId(id);
        // 此时该任务下已存在至少一个‘处理中’的异常项目，若不存在未发起整改的，则任务异常处理状态也为‘处理中’
        Integer unRepairCount = taskMapper.countUnRepairItem(task.getId());
        if (unRepairCount < 1) {
            task.setExcepHandel(ExceptProcessStatus.PROCESSING);
            taskService.saveOrUpdate(task);
        }
    }

    @Override
    public void repairFinish(Long id) {
        PatrolRecordItem recordItem = getById(id);
        recordItem.setExceptHandel(ExceptProcessStatus.PROCESSING_FINISH);
        saveOrUpdate(recordItem);
        PatrolTask task = mapper.selectTaskByItemId(id);
        Integer unRepairCount = taskMapper.countUnRepairItem(task.getId());
        Integer unRepairFinishItem = taskMapper.countUnRepairFinishItem(task.getId());
        /**
         * 此时该任务下的一个异常检查项目处理结束，若依然存在未发起处理的检查项目，则任务异常处理状态未‘等待处理’
         * 若无未发起异常处理的，但有正在处理中的异常检查项目，则任务异常处理状态为‘处理中’
         * 若无未发起的，也无发起未完成的，则任务异常处理状态为‘处理完成’
         */
        if (unRepairCount > 0) {
            task.setExcepHandel(ExceptProcessStatus.WAITING_TO_PROCESS);
        } else if (unRepairFinishItem > 0) {
            task.setExcepHandel(ExceptProcessStatus.PROCESSING);
        } else {
            task.setExcepHandel(ExceptProcessStatus.PROCESSING_FINISH);
        }
        taskService.saveOrUpdate(task);
    }

    @Override
    public List<WebTaskRecordItemVo> getExceptItemByTask(Long taskId) {
        List<WebTaskRecordItemVo> itemList = mapper.getExRecordByTaskId(taskId);
        if (CollectionUtil.isNotEmpty(itemList)) {
            itemList.forEach(item -> {
                if (StringUtils.isNotBlank(item.getDeviceCode())) {
                    // 拼接name和code
                    item.setDeviceName(
                            new StringBuilder()
                                    .append(item.getDeviceName())
                                    .append("[")
                                    .append(item.getDeviceCode())
                                    .append("]")
                                    .toString()
                    );
                }
            });
        }
        return itemList;
    }

    @Override
    public List<WebTaskRecordDeviceVo> getExceptItemByRecord(Long recordId) {
        List<WebTaskRecordItemVo> itemList = mapper.getExItemByRecord(recordId);
        ArrayList<WebTaskRecordDeviceVo> result = new ArrayList<>();
        if (CollectionUtil.isEmpty(itemList)) {
            return new ArrayList<>();
        }
        itemList.forEach(item -> {
            boolean needUnit = !Constants.DEVICE_STOP_NO_CHECK.equals(item.getCheckResult())
                    && !Constants.DEVICE_STOP_NO_CHECK.equals(item.getCheckResult1())
                    && !Constants.DEVICE_STOP_NO_CHECK.equals(item.getCheckResult2());
            item.setNeedUnit(needUnit);
        });
        Map<Long, List<WebTaskRecordItemVo>> deviceGroup = itemList.stream().collect(Collectors.groupingBy(WebTaskRecordItemVo::getDeviceId));
        deviceGroup.forEach((key, value) -> {
            WebTaskRecordDeviceVo deviceVo = new WebTaskRecordDeviceVo();
            WebTaskRecordItemVo firstItemVo = value.get(0);
            deviceVo.setDeviceName(firstItemVo.getDeviceName());
            deviceVo.setCheckDeviceId(firstItemVo.getDeviceId());
            // 有code拼上code
            deviceVo.setNameAndCode(StringUtils.isNotBlank(firstItemVo.getDeviceCode()) ? firstItemVo.getDeviceName() + "[" + firstItemVo.getDeviceCode() + "]" : firstItemVo.getDeviceName());
            deviceVo.setItemList(value);
            result.add(deviceVo);
        });
        return result;
    }

    @Override
    public Page<TaskRecordItemDto> getLastTaskRecordItemByTaskId(Integer pageNo, Integer size, Long taskId, String pointName, String deviceNameOrCode) {
        Page<TaskRecordItemDto> page = new Page<>(pageNo + 1, size);
        return getTaskRecordItem(page, taskId, pointName, deviceNameOrCode);
    }


    @Override
    public Page<TaskRecordItemDto> getTaskRecordItem(Page<TaskRecordItemDto> page, Long taskId, String pointName, String deviceNameOrCode) {
        return mapper.getTaskRecordItem(page, taskId, pointName, deviceNameOrCode);
    }

    @Override
    public List<ItemCheckResultDto> getItemCheckResultByTaskAndCkProject(List<Long> taskIds, List<Long> ckProjectIds) {
        return mapper.getItemCheckResultByTaskAndCkProject(taskIds, ckProjectIds);
    }

    @Override
    public List<TaskRecordItemDto> findWfRecordItemList() {
        return mapper.findWfRecordItemList();
    }

    @Override
    public boolean updateWfRecordItemById(String status, String exceptHandel, Long id) {
        if (StringUtils.isNotBlank(status)) {
            return mapper.updateWfRecordItemById(status, exceptHandel, id);
        } else {
            log.warn("updateWfRecordItemByIds error. id[{}],status:{}", id, status);
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void repairNewWf(Long itemId, String wfProcessInsId, String wfProcessStatus) {
            mapper.updateRecordItemRepairStatusAndWfStatus(itemId, ExceptProcessStatus.PROCESSING,
                    wfProcessInsId, wfProcessStatus);
    }

    @Override
    public void updatePatrol(Long id, String state) {
        PatrolRecordItem patrolRecordItem = mapper.selectById(id);
        if (patrolRecordItem != null) {
            patrolRecordItem.setExceptHandel(state);
            mapper.updateById(patrolRecordItem);
        }
    }
}
